package com.hmdp.utils;

import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.hmdp.entity.VoucherOrder;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class SaveDelayCloseRequestToBackup {
    /**
     * 延迟关单消息兜底存储（Redis+本地文件）
     */
    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    public void saveDelayCloseRequestToRedis(Long orderId, VoucherOrder voucherOrder) {
        // 1. 封装延迟消息内容
        Map<String, Object> delayMsg = new HashMap<>();
        delayMsg.put("orderId", orderId);
        delayMsg.put("voucherId", voucherOrder.getVoucherId());
        delayMsg.put("userId", voucherOrder.getUserId());
        String delayMsgJson = JSONUtil.toJsonStr(delayMsg);

        // 2. 写入Redis延迟消息兜底队列
        String delayBackupKey = "seckill:mq:delay:backup";
        try {
            stringRedisTemplate.opsForList().leftPush(delayBackupKey, delayMsgJson);
            stringRedisTemplate.expire(delayBackupKey, 7, TimeUnit.DAYS);
        } catch (Exception e) {
            log.error("订单{}延迟关单消息写入Redis兜底失败", orderId, e);
            // Redis失败则写入本地文件
            saveDelayMsgToLocalFile(orderId, delayMsgJson);
        }
    }

    /**
     * 延迟消息本地文件兜底
     */
    private void saveDelayMsgToLocalFile(Long orderId, String delayMsgJson) {
        String dateDir = DateUtil.today();
        String fileName = String.format("seckill_delay_backup_%s.log", dateDir);
        String filePath = String.format("/data/seckill/delay_backup/%s", fileName);

        File dir = new File("/data/seckill/delay_backup/");
        if (!dir.exists()) {
            dir.mkdirs();
        }

        try (BufferedWriter writer = new BufferedWriter(new FileWriter(filePath, true))) {
            writer.write(delayMsgJson);
            writer.newLine();
            log.info("订单{}延迟关单消息写入本地兜底文件：{}", orderId, filePath);
        } catch (IOException e) {
            log.error("订单{}延迟关单消息写入本地文件失败", orderId, e);
            sendAlarm("订单" + orderId + "延迟关单消息本地兜底失败！");
        }
    }
    private void sendAlarm(String alarmMsg) {
        // 1. 先打印错误日志（必做）
        log.error("秒杀系统告警：{}", alarmMsg);
    }
}
